from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.decorators import login_required, user_passes_test
from django.contrib import messages
from django.http import JsonResponse
from django.db.models import Q, Avg, Sum, Count
from django.utils import timezone
from django.core.paginator import Paginator
from django.views.decorators.csrf import csrf_exempt
import requests
import json
from datetime import datetime, timedelta

from .models import Movie, Screening, Order, Seat, UserProfile, MovieReview, CinemaHall
from .forms import UserRegistrationForm, MovieForm, ScreeningForm, MovieReviewForm, UserProfileForm

def is_admin(user):
    """检查用户是否为管理员"""
    return user.is_staff

def home(request):
    """首页"""
    movies = Movie.objects.filter(is_active=True).order_by('-created_at')[:6]
    upcoming_movies = Movie.objects.filter(
        release_date__gte=timezone.now().date(),
        is_active=True
    ).order_by('release_date')[:4]
    
    context = {
        'movies': movies,
        'upcoming_movies': upcoming_movies,
    }
    return render(request, 'cinema/home.html', context)

def movie_list(request):
    """电影列表"""
    movies = Movie.objects.filter(is_active=True)
    
    # 搜索功能
    search = request.GET.get('search')
    if search:
        movies = movies.filter(
            Q(title__icontains=search) |
            Q(director__icontains=search) |
            Q(actors__icontains=search) |
            Q(genre__icontains=search)
        )
    
    # 分页
    paginator = Paginator(movies, 12)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    context = {
        'page_obj': page_obj,
        'search': search,
    }
    return render(request, 'cinema/movie_list.html', context)

def movie_detail(request, movie_id):
    """电影详情"""
    movie = get_object_or_404(Movie, id=movie_id)
    screenings = Screening.objects.filter(
        movie=movie,
        start_time__gte=timezone.now(),
        is_active=True
    ).order_by('start_time')
    
    # 获取评论
    reviews = MovieReview.objects.filter(movie=movie).order_by('-created_at')
    avg_rating = reviews.aggregate(Avg('rating'))['rating__avg'] or 0
    
    # 用户评论表单
    if request.user.is_authenticated:
        user_review = MovieReview.objects.filter(user=request.user, movie=movie).first()
        review_form = MovieReviewForm(instance=user_review) if user_review else MovieReviewForm()
    else:
        review_form = None
    
    context = {
        'movie': movie,
        'screenings': screenings,
        'reviews': reviews,
        'avg_rating': avg_rating,
        'review_form': review_form,
    }
    return render(request, 'cinema/movie_detail.html', context)

def register(request):
    """用户注册"""
    if request.method == 'POST':
        form = UserRegistrationForm(request.POST)
        if form.is_valid():
            user = form.save()
            # 创建用户资料
            UserProfile.objects.create(
                user=user,
                phone=form.cleaned_data.get('phone', '')
            )
            messages.success(request, '注册成功！请登录。')
            return redirect('login')
    else:
        form = UserRegistrationForm()
    
    return render(request, 'cinema/register.html', {'form': form})

def user_login(request):
    """用户登录"""
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            messages.success(request, f'欢迎回来，{user.username}！')
            return redirect('home')
        else:
            messages.error(request, '用户名或密码错误。')
    
    return render(request, 'cinema/login.html')

def user_logout(request):
    """用户登出"""
    logout(request)
    messages.info(request, '您已成功登出。')
    return redirect('home')

@login_required
def profile(request):
    """用户资料"""
    profile, created = UserProfile.objects.get_or_create(user=request.user)
    
    if request.method == 'POST':
        form = UserProfileForm(request.POST, request.FILES, instance=profile)
        if form.is_valid():
            form.save()
            messages.success(request, '资料更新成功！')
            return redirect('profile')
    else:
        form = UserProfileForm(instance=profile)
    
    # 获取用户订单，按创建时间倒序排列
    try:
        orders = Order.objects.filter(user=request.user).select_related(
            'screening__movie', 'screening__hall'
        ).prefetch_related('seats').order_by('-created_at')
    except Exception as e:
        orders = []
        messages.error(request, f'获取订单记录失败：{str(e)}')
    
    context = {
        'form': form,
        'profile': profile,
        'orders': orders,
    }
    return render(request, 'cinema/profile.html', context)

@login_required
def book_ticket(request, screening_id):
    """订票页面"""
    screening = get_object_or_404(Screening, id=screening_id, is_active=True)
    
    if request.method == 'POST':
        seat_ids = request.POST.getlist('seats')
        if seat_ids:
            # 检查座位是否已被预订
            existing_orders = Order.objects.filter(
                screening=screening,
                status__in=['pending', 'paid', 'completed']
            ).values_list('seats__id', flat=True)
            
            # 过滤掉已被预订的座位
            available_seats = []
            for seat_id in seat_ids:
                if int(seat_id) not in existing_orders:
                    available_seats.append(seat_id)
            
            if available_seats:
                seats = Seat.objects.filter(id__in=available_seats, is_active=True)
                if seats.count() == len(available_seats):  # 确保所有座位都存在
                    total_amount = len(seats) * screening.price
                    
                    try:
                        # 创建订单
                        order = Order.objects.create(
                            user=request.user,
                            screening=screening,
                            total_amount=total_amount
                        )
                        order.seats.set(seats)
                        
                        messages.success(request, f'购票成功！订单号：{order.order_id}')
                        return redirect('order_detail', order_id=order.id)
                    except Exception as e:
                        messages.error(request, f'创建订单失败：{str(e)}')
                        return redirect('book_ticket', screening_id=screening_id)
                else:
                    messages.error(request, '部分座位不存在或已被预订，请重新选择。')
            else:
                messages.error(request, '所选座位已被预订，请重新选择。')
        else:
            messages.error(request, '请选择座位。')
    
    # 获取已售座位
    sold_seats = Order.objects.filter(
        screening=screening,
        status__in=['pending', 'paid', 'completed']
    ).values_list('seats__id', flat=True)
    
    # 获取影厅座位
    seats = Seat.objects.filter(hall=screening.hall, is_active=True).order_by('row', 'column')
    
    # 如果没有座位数据，创建默认座位
    if not seats.exists():
        # 创建默认座位（10行10列）
        for row in range(1, 11):
            for col in range(1, 11):
                seat_number = f"{chr(64 + row)}{col:02d}"  # A01, A02, ..., J10
                Seat.objects.create(
                    hall=screening.hall,
                    row=chr(64 + row),
                    column=col,
                    seat_number=seat_number
                )
        seats = Seat.objects.filter(hall=screening.hall, is_active=True).order_by('row', 'column')
    
    context = {
        'screening': screening,
        'seats': seats,
        'sold_seats': sold_seats,
    }
    return render(request, 'cinema/book_ticket.html', context)

@login_required
def order_detail(request, order_id):
    """订单详情"""
    try:
        order = get_object_or_404(Order, id=order_id, user=request.user)
    except:
        messages.error(request, '订单不存在或您没有权限查看此订单。')
        return redirect('profile')
    
    if request.method == 'POST':
        action = request.POST.get('action')
        if action == 'pay':
            try:
                order.status = 'paid'
                order.save()
                messages.success(request, '支付成功！')
            except Exception as e:
                messages.error(request, f'支付失败：{str(e)}')
        elif action == 'cancel':
            try:
                order.status = 'cancelled'
                order.save()
                messages.info(request, '订单已取消。')
            except Exception as e:
                messages.error(request, f'取消订单失败：{str(e)}')
    
    # 重新获取订单数据以确保最新状态
    order.refresh_from_db()
    
    return render(request, 'cinema/order_detail.html', {'order': order})

@login_required
def add_review(request, movie_id):
    """添加评论"""
    if request.method == 'POST':
        movie = get_object_or_404(Movie, id=movie_id)
        form = MovieReviewForm(request.POST)
        if form.is_valid():
            review, created = MovieReview.objects.get_or_create(
                user=request.user,
                movie=movie,
                defaults=form.cleaned_data
            )
            if not created:
                review.rating = form.cleaned_data['rating']
                review.comment = form.cleaned_data['comment']
                review.save()
            
            messages.success(request, '评论提交成功！')
    
    return redirect('movie_detail', movie_id=movie_id)

# 管理员视图
@user_passes_test(is_admin)
def admin_dashboard(request):
    """管理员仪表板"""
    from django.contrib.auth.models import User
    
    # 基础统计
    total_movies = Movie.objects.count()
    total_orders = Order.objects.count()
    total_users = User.objects.count()
    
    # 今日统计
    today = timezone.now().date()
    today_orders = Order.objects.filter(created_at__date=today).count()
    today_revenue = Order.objects.filter(
        created_at__date=today, 
        status__in=['paid', 'completed']
    ).aggregate(Sum('total_amount'))['total_amount__sum'] or 0
    
    # 活跃电影和场次
    active_movies = Movie.objects.filter(is_active=True).count()
    today_screenings = Screening.objects.filter(
        start_time__date=today,
        is_active=True
    ).count()
    
    # 新用户统计
    new_users_today = User.objects.filter(date_joined__date=today).count()
    
    # 最近订单
    recent_orders = Order.objects.select_related('user', 'screening__movie').order_by('-created_at')[:10]
    
    # 热门电影（按场次数量）
    popular_movies = Movie.objects.annotate(
        screening_count=Count('screening')
    ).filter(is_active=True).order_by('-screening_count')[:5]
    
    # 图表数据 - 最近7天的订单趋势
    chart_labels = []
    chart_data = []
    for i in range(6, -1, -1):
        date = today - timedelta(days=i)
        chart_labels.append(date.strftime('%m-%d'))
        order_count = Order.objects.filter(created_at__date=date).count()
        chart_data.append(order_count)
    
    context = {
        'total_movies': total_movies,
        'total_orders': total_orders,
        'total_users': total_users,
        'today_orders': today_orders,
        'today_revenue': today_revenue,
        'active_movies': active_movies,
        'today_screenings': today_screenings,
        'new_users_today': new_users_today,
        'recent_orders': recent_orders,
        'popular_movies': popular_movies,
        'chart_labels': json.dumps(chart_labels),
        'chart_data': json.dumps(chart_data),
    }
    return render(request, 'cinema/admin/dashboard.html', context)

@user_passes_test(is_admin)
def movie_management(request):
    """电影管理"""
    movies = Movie.objects.all().order_by('-created_at')
    
    if request.method == 'POST':
        action = request.POST.get('action')
        movie_id = request.POST.get('movie_id')
        movie = get_object_or_404(Movie, id=movie_id)
        
        if action == 'delete':
            movie.delete()
            messages.success(request, '电影删除成功！')
        elif action == 'toggle':
            movie.is_active = not movie.is_active
            movie.save()
            messages.success(request, f'电影状态已更新！')
    
    context = {
        'movies': movies,
    }
    return render(request, 'cinema/admin/movie_management.html', context)

@user_passes_test(is_admin)
def add_movie(request):
    """添加电影"""
    if request.method == 'POST':
        form = MovieForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            messages.success(request, '电影添加成功！')
            return redirect('movie_management')
    else:
        form = MovieForm()
    
    return render(request, 'cinema/admin/add_movie.html', {'form': form})

@user_passes_test(is_admin)
def edit_movie(request, movie_id):
    """编辑电影"""
    movie = get_object_or_404(Movie, id=movie_id)
    
    if request.method == 'POST':
        form = MovieForm(request.POST, request.FILES, instance=movie)
        if form.is_valid():
            form.save()
            messages.success(request, '电影更新成功！')
            return redirect('movie_management')
    else:
        form = MovieForm(instance=movie)
    
    return render(request, 'cinema/admin/edit_movie.html', {'form': form, 'movie': movie})

@user_passes_test(is_admin)
def screening_management(request):
    """场次管理"""
    screenings = Screening.objects.all().order_by('-start_time')
    
    if request.method == 'POST':
        action = request.POST.get('action')
        screening_id = request.POST.get('screening_id')
        screening = get_object_or_404(Screening, id=screening_id)
        
        if action == 'delete':
            screening.delete()
            messages.success(request, '场次删除成功！')
        elif action == 'toggle':
            screening.is_active = not screening.is_active
            screening.save()
            messages.success(request, f'场次状态已更新！')
    
    context = {
        'screenings': screenings,
    }
    return render(request, 'cinema/admin/screening_management.html', context)

@user_passes_test(is_admin)
def add_screening(request):
    """添加场次"""
    if request.method == 'POST':
        form = ScreeningForm(request.POST)
        if form.is_valid():
            screening = form.save(commit=False)
            # 计算结束时间
            movie = screening.movie
            screening.end_time = screening.start_time + timedelta(minutes=movie.duration)
            screening.save()
            messages.success(request, '场次添加成功！')
            return redirect('screening_management')
    else:
        form = ScreeningForm()
    
    return render(request, 'cinema/admin/add_screening.html', {'form': form})

@user_passes_test(is_admin)
def order_management(request):
    """订单管理"""
    orders = Order.objects.all().order_by('-created_at')
    
    if request.method == 'POST':
        action = request.POST.get('action')
        order_id = request.POST.get('order_id')
        order = get_object_or_404(Order, id=order_id)
        
        if action == 'complete':
            order.status = 'completed'
            order.save()
            messages.success(request, '订单状态已更新！')
        elif action == 'cancel':
            order.status = 'cancelled'
            order.save()
            messages.success(request, '订单已取消！')
    
    context = {
        'orders': orders,
    }
    return render(request, 'cinema/admin/order_management.html', context)

# DeepSeek API集成
def get_movie_recommendations(request):
    """获取电影推荐（使用DeepSeek API）"""
    from django.conf import settings
    
    if not hasattr(settings, 'DEEPSEEK_API_KEY') or settings.DEEPSEEK_API_KEY == 'your_deepseek_api_key_here':
        return JsonResponse({'error': 'API密钥未配置'}, status=400)
    
    try:
        movies = Movie.objects.filter(is_active=True)[:5]
        movie_list = [f"{movie.title} ({movie.genre})" for movie in movies]
        
        prompt = f"""
        基于以下电影列表，为用户推荐3部类似的电影：
        {', '.join(movie_list)}
        
        请以JSON格式返回推荐结果，包含电影名称、推荐理由和预期评分。
        """
        
        headers = {
            'Authorization': f'Bearer {settings.DEEPSEEK_API_KEY}',
            'Content-Type': 'application/json'
        }
        
        data = {
            'model': 'deepseek-chat',
            'messages': [{'role': 'user', 'content': prompt}],
            'max_tokens': 500
        }
        
        response = requests.post(settings.DEEPSEEK_API_URL, headers=headers, json=data)
        
        if response.status_code == 200:
            result = response.json()
            recommendations = result['choices'][0]['message']['content']
            return JsonResponse({'recommendations': recommendations})
        else:
            return JsonResponse({'error': 'API请求失败'}, status=500)
            
    except Exception as e:
        return JsonResponse({'error': str(e)}, status=500)

@user_passes_test(is_admin)
def user_management(request):
    """用户管理"""
    from django.contrib.auth.models import User
    
    users = User.objects.select_related('userprofile').all().order_by('-date_joined')
    
    if request.method == 'POST':
        action = request.POST.get('action')
        user_id = request.POST.get('user_id')
        user = get_object_or_404(User, id=user_id)
        
        if action == 'toggle_staff':
            user.is_staff = not user.is_staff
            user.save()
            messages.success(request, f'用户"{user.username}"的管理员权限已更新！')
        elif action == 'toggle_active':
            user.is_active = not user.is_active
            user.save()
            messages.success(request, f'用户"{user.username}"的状态已更新！')
        elif action == 'delete':
            user.delete()
            messages.success(request, f'用户"{user.username}"已删除！')
    
    # 统计信息
    today = timezone.now().date()
    today_new_users = User.objects.filter(date_joined__date=today).count()
    
    context = {
        'users': users,
        'today_new_users': today_new_users,
    }
    return render(request, 'cinema/admin/user_management.html', context)

@user_passes_test(is_admin)
def hall_management(request):
    """影厅管理"""
    halls = CinemaHall.objects.all().order_by('name')
    
    if request.method == 'POST':
        action = request.POST.get('action')
        hall_id = request.POST.get('hall_id')
        hall = get_object_or_404(CinemaHall, id=hall_id)
        
        if action == 'toggle':
            hall.is_active = not hall.is_active
            hall.save()
            messages.success(request, f'影厅"{hall.name}"的状态已更新！')
        elif action == 'delete':
            hall.delete()
            messages.success(request, f'影厅"{hall.name}"已删除！')
    
    # 统计信息
    active_halls_count = halls.filter(is_active=True).count()
    total_seats = Seat.objects.count()
    total_screenings = Screening.objects.count()
    
    context = {
        'halls': halls,
        'active_halls_count': active_halls_count,
        'total_seats': total_seats,
        'total_screenings': total_screenings,
    }
    return render(request, 'cinema/admin/hall_management.html', context)

@user_passes_test(is_admin)
def review_management(request):
    """评论管理"""
    reviews = MovieReview.objects.select_related('user', 'movie').all().order_by('-created_at')
    
    if request.method == 'POST':
        action = request.POST.get('action')
        review_id = request.POST.get('review_id')
        review = get_object_or_404(MovieReview, id=review_id)
        
        if action == 'delete':
            review.delete()
            messages.success(request, '评论已删除！')
    
    # 统计信息
    avg_rating = reviews.aggregate(Avg('rating'))['rating__avg'] or 0
    unique_users = reviews.values('user').distinct().count()
    unique_movies = reviews.values('movie').distinct().count()
    movies = Movie.objects.all()
    
    # 评分分布
    rating_counts = {}
    for i in range(1, 6):
        rating_counts[i] = reviews.filter(rating=i).count()
    
    context = {
        'reviews': reviews,
        'avg_rating': avg_rating,
        'unique_users': unique_users,
        'unique_movies': unique_movies,
        'movies': movies,
        'rating_counts': rating_counts,
    }
    return render(request, 'cinema/admin/review_management.html', context)

@csrf_exempt
def chat_api(request):
    """聊天API接口"""
    if request.method == 'POST':
        try:
            data = json.loads(request.body)
            user_message = data.get('message', '').strip()
            
            if not user_message:
                return JsonResponse({'error': '消息不能为空'}, status=400)
            
            # DeepSeek API配置
            DEEPSEEK_API_KEY = 'sk-52a19b6ea5a146f4b0dfeebf4474fba7'
            DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/chat/completions'
            
            # 获取当前电影信息用于上下文
            movies = Movie.objects.filter(is_active=True)[:5]
            movie_context = ""
            if movies:
                movie_list = [f"{movie.title}（{movie.genre}，评分{movie.rating}）" for movie in movies]
                movie_context = f"当前热门电影：{', '.join(movie_list)}。"
            
            # 构建系统提示
            system_prompt = f"""你是一个电影院票务系统的AI助手，专门帮助用户解决购票相关问题。

{movie_context}

你可以帮助用户：
1. 查询电影信息、场次安排
2. 解释购票流程和注意事项
3. 回答关于会员服务、优惠活动的问题
4. 提供观影建议和推荐
5. 解答系统使用相关问题

请用友好、专业的语气回答，回答要简洁明了，不超过200字。"""
            
            # 调用DeepSeek API
            headers = {
                'Authorization': f'Bearer {DEEPSEEK_API_KEY}',
                'Content-Type': 'application/json'
            }
            
            payload = {
                'model': 'deepseek-chat',
                'messages': [
                    {
                        'role': 'system',
                        'content': system_prompt
                    },
                    {
                        'role': 'user',
                        'content': user_message
                    }
                ],
                'max_tokens': 500,
                'temperature': 0.7
            }
            
            response = requests.post(DEEPSEEK_API_URL, headers=headers, json=payload, timeout=30)
            
            if response.status_code == 200:
                result = response.json()
                bot_response = result['choices'][0]['message']['content']
                return JsonResponse({
                    'response': bot_response,
                    'timestamp': timezone.now().isoformat()
                })
            else:
                error_msg = f'API请求失败: {response.status_code}'
                if response.text:
                    try:
                        error_data = response.json()
                        error_msg = error_data.get('error', {}).get('message', error_msg)
                    except:
                        pass
                return JsonResponse({'error': error_msg}, status=500)
                
        except json.JSONDecodeError:
            return JsonResponse({'error': '无效的JSON格式'}, status=400)
        except requests.exceptions.Timeout:
            return JsonResponse({'error': '请求超时，请稍后重试'}, status=408)
        except requests.exceptions.RequestException as e:
            return JsonResponse({'error': f'网络请求错误: {str(e)}'}, status=500)
        except Exception as e:
            return JsonResponse({'error': f'服务器错误: {str(e)}'}, status=500)
    
    return JsonResponse({'error': '只支持POST请求'}, status=405)
